#include "StdAfx.h"
#include "Reciver.h"


Reciver::Reciver(void)
{
	port = new serialport("COM1");
	FillMemory(&recivedData, sizeof(packet), 0);

	useCRC = FALSE;
	packetNumber = 1;
	crc = 0;
}

Reciver::Reciver(string _port)
{
	port = new serialport(_port.c_str());
	FillMemory(&recivedData, sizeof(packet), 0);

	useCRC = FALSE;
	packetNumber = 1;
	crc = 0;
}


Reciver::~Reciver(void)
{
	delete port;
}

BOOL Reciver::reciveFile(BOOL CRC)
{
	DWORD counter;
	useCRC = CRC;
	packetNumber = 1;
	WORD finalPacketSize;

	/*
	hFile = OpenFile(fileName.c_str(), &openFileStruct, OF_CREATE | OF_WRITE);
	if(hFile == HFILE_ERROR)
	{
		cout << "Blad otwarcia pliku. " << GetLastError() << endl;
		return FALSE;
	}
	*/


	if(useCRC)
	{
		initSign = c;
		finalPacketSize = sizeof(recivedData);
	}
	else
	{
		initSign = nak;
		finalPacketSize = sizeof(recivedData) - 1;
	}

	BOOL initializationFinish = FALSE;
	BYTE failedRetry = 0;

	while(true)
	{
		if(initializationFinish)
		{	
			port->readABuffer(&recivedData, finalPacketSize);
		}
		else
		{
			for (int i = 0; i <= 6; i++)
			{
				cout << "Inicjalizacja transmisji" << endl;

				port->writeABuffer(&initSign, 1);
				port->readABuffer(&recivedData, finalPacketSize);

				if(recivedData.startOfHeader == soh)
				{
					initializationFinish = TRUE;
					cout << "Inicjalizacja powiodla sie. Odbieranie pliku..." << endl;

					//Przygotowanie nazwy pliku
					time_t rawtime;
					struct tm * timeinfo;
					char buffer [80];

					time ( &rawtime );
					timeinfo = localtime ( &rawtime );
					strftime (buffer,80,"%d%m%y_%H%M",timeinfo);

					string filename(buffer);
					filename += ".txt";

					//Stworzenie pliku raportu
					hFile = OpenFile(filename.c_str(), &openFileStruct, OF_CREATE | OF_WRITE);
					if(hFile == HFILE_ERROR)
					{
						cout << "Blad otwarcia pliku. " << GetLastError() << endl;
						return FALSE;
					}

					break;
				}

				if(i == 6)
				{
					cout << "Inicjalizacja polaczenia nie powidla sie" << endl;
					return FALSE;
				}
			}
		}


		switch(recivedData.startOfHeader)
		{
		case eot:
			{
				cout << "Zakonczenie transmisji." << endl;
				initSign = ack;
				port->writeABuffer(&initSign, 1);
				return TRUE;
				break;
			}
		case soh:
			{
				if(checkPacket() && packetNumber == recivedData.packetNum)
				{
					initSign = ack;

					packetNumber++;

					if(packetNumber > 255)
					{
						packetNumber = 1;
					}

					WriteFile((HANDLE)hFile, &recivedData.fileData, sizeof(recivedData.fileData), &counter, NULL);

					failedRetry = 0;
				}
				else
				{
					initSign = nak;
					failedRetry++;
				}
				break;
			}
		case can:
			{
				return FALSE;
				break;
			}
		default:
			{
				initSign = nak;
				failedRetry++;
			}
		}

		if(failedRetry >= 6)
		{
			cout << "Bledy transmisji." << endl;
			return FALSE;
		}
		
		port->writeABuffer(&initSign, 1);

		FillMemory(&recivedData, sizeof(recivedData), 0);
	}

	return TRUE;
}

BOOL Reciver::checkPacket()
{

	if(useCRC)
	{
		WORD tmp = CRC();
		BYTE highCRC = tmp >> 8;
		BYTE lowCRC = tmp;

		if(highCRC == recivedData.checkSum1 && lowCRC == recivedData.checkSum2)
		{
			return TRUE;
		}
		
	}
	else
	{
		BYTE tmpChceksum = checkSum();

		if(tmpChceksum == recivedData.checkSum1)
		{
			return TRUE;
		}
	}

	return FALSE;
}


WORD Reciver::CRC()
{
	crc	= 0x0000;
	for (int i = 0; i < sizeof(recivedData.fileData); i++ )
	{
		crc = crc ^ (int)recivedData.fileData[i] << 8;
		for (int j = 0; j < 8; ++j)
		{
			if (crc & 0x8000)
			{
				crc = crc << 1 ^ 0x1021;
			}
			else
			{
				crc = crc << 1;
			}
		}
	}
	return (crc	& 0xFFFF);
}

BYTE Reciver::checkSum()
{
	checksum = 0x00;

	for(int i = 0; i < sizeof(recivedData.fileData); i++)
	{
		checksum += (BYTE)recivedData.fileData[i];
	}

	return checksum;

}